1 module unde.global_state; 2 3 import unde.games.dizzy.omega.main; 4 import unde.file_manager.events; 5 import unde.keybar.lib; 6 7 import std.format; 8 import std.conv; 9 import std.stdio; 10 11 import std.datetime; 12 13 import std.string; 14 15 import derelict.sdl2.sdl; 16 import derelict.sdl2.image; 17 18 import derelict.opengl3.gl3; 19 import derelict.opengl3.gl; 20 import derelict.sdl2.mixer; 21 22 public import core.sys.posix.sys.types; 23 24 import std.file; 25 26 struct Games 27 { 28 DizzyOmega dizzy_omega; 29 } 30 31 class GlobalState 32 { 33 Games games; 34 SDL_Window* window; 35 SDL_Renderer* renderer; 36 bool finish = false; 37 uint frame; //Frame which renders 38 uint time; //Time from start of program in ms 39 uint fps_frames; 40 uint fps_time; 41 42 bool window_shown; 43 44 KeyBar_Buttons keybar; 45 SDL_Rect screen; 46 47 void createWindow(size_t display = 0) 48 { 49 int displays = SDL_GetNumVideoDisplays(); 50 51 int x = SDL_WINDOWPOS_UNDEFINED; 52 int y = SDL_WINDOWPOS_UNDEFINED; 53 54 if (display > 0 && display < displays) 55 { 56 SDL_Rect displayBounds; 57 auto r = SDL_GetDisplayBounds(cast(int) display, &displayBounds); 58 if (r != 0) 59 { 60 writefln("Error SDL_GetDisplayBounds display %d: %s", display, SDL_GetError().fromStringz()); 61 } 62 else 63 { 64 x = displayBounds.x; 65 y = displayBounds.y; 66 } 67 } 68 69 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); 70 //The window we'll be rendering to 71 window = SDL_CreateWindow( 72 "Dizzy Omega", // window title 73 x, // initial x position 74 y, // initial y position 75 0, // width, in pixels 76 0, // height, in pixels 77 SDL_WINDOW_FULLSCREEN_DESKTOP | 78 SDL_WINDOW_RESIZABLE | 79 SDL_WINDOW_OPENGL // flags 80 ); 81 if( window == null ) 82 { 83 throw new Exception(format("Error while create window: %s", 84 SDL_GetError().to!string())); 85 } 86 } 87 88 void createRenderer() 89 { 90 /* To render we need only renderer (which connected to window) and 91 surfaces to draw it */ 92 SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); 93 renderer = SDL_CreateRenderer( 94 window, 95 -1, 96 SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE 97 ); 98 if (!renderer) 99 { 100 writefln("Error while create accelerated renderer: %s", 101 SDL_GetError().to!string()); 102 renderer = SDL_CreateRenderer( 103 window, 104 -1, 105 SDL_RENDERER_TARGETTEXTURE 106 ); 107 } 108 if (!renderer) 109 { 110 throw new Exception(format("Error while create renderer: %s", 111 SDL_GetError().to!string())); 112 } 113 114 SDL_RenderClear(renderer); 115 116 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 117 118 int r = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); 119 if (r < 0) 120 { 121 throw new Exception( 122 format("Error while set render draw blend mode: %s", 123 SDL_GetError().to!string())); 124 } 125 126 SDL_bool res = SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); 127 if (!res) 128 { 129 throw new Exception( 130 format("Can't set filter mode")); 131 } 132 } 133 134 void initGL() 135 { 136 DerelictGL.load(); 137 DerelictGL3.load(); 138 DerelictGL3.reload(); 139 140 glEnable(GL_BLEND); 141 glEnable(GL_TEXTURE_2D); 142 glEnable(GL_LIGHTING); 143 glEnable(GL_LIGHT0); 144 glLightfv(GL_LIGHT0, GL_POSITION, [-5f, -5f, 10.0f, 1.0f].ptr); 145 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, [0.5f, 0.5f, -1.0f].ptr); 146 glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, 64); 147 glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, 90); 148 149 glEnable(GL_LIGHT1); 150 glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.0f, 0.08f, 0.10f, 1.0f].ptr); 151 glLightfv(GL_LIGHT1, GL_SPECULAR, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 152 glLightfv(GL_LIGHT1, GL_POSITION, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 153 //glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, [0.5f, 0.5f, -1.0f].ptr); 154 glLighti(GL_LIGHT1, GL_SPOT_EXPONENT, 90); 155 glLighti(GL_LIGHT1, GL_SPOT_CUTOFF, 180); 156 glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0); 157 glLighti(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 3); 158 159 glEnable(GL_LIGHT2); 160 glLightfv(GL_LIGHT2, GL_DIFFUSE, [0.0f, 0.08f, 0.10f, 1.0f].ptr); 161 glLightfv(GL_LIGHT2, GL_SPECULAR, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 162 glLightfv(GL_LIGHT2, GL_POSITION, [0.0f, 0.0f, 0.0f, 1.0f].ptr); 163 //glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, [0.5f, 0.5f, -1.0f].ptr); 164 glLighti(GL_LIGHT2, GL_SPOT_EXPONENT, 90); 165 glLighti(GL_LIGHT2, GL_SPOT_CUTOFF, 180); 166 glLighti(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 0); 167 glLighti(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 1); 168 169 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 170 glEnable(GL_NORMALIZE); 171 172 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 173 } 174 175 void syncTime() 176 { 177 time = SDL_GetTicks(); 178 } 179 180 void startGame() 181 { 182 if (games.dizzy_omega is null) 183 { 184 games.dizzy_omega = new DizzyOmega(this); 185 } 186 games.dizzy_omega.toGame(this); 187 setup_keybar(this); 188 } 189 190 void stopGame() 191 { 192 games.dizzy_omega.fromGame(this); 193 finish = true; 194 } 195 196 void initSDL(size_t display = 0) 197 { 198 DerelictSDL2.load(); 199 200 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 ) 201 { 202 throw new Exception(format("Error while SDL initializing: %s", 203 SDL_GetError().to!string() )); 204 } 205 206 createWindow(display); 207 208 createRenderer(); 209 210 SDL_GetWindowSize(window, &screen.w, &screen.h); 211 212 initGL(); 213 214 screen.w -= 32*6; 215 } 216 217 void deInitSDL() 218 { 219 SDL_DestroyRenderer(renderer); 220 SDL_DestroyWindow(window); 221 SDL_Quit(); 222 } 223 224 void initSDLImage() 225 { 226 DerelictSDL2Image.load(); 227 228 auto flags = IMG_INIT_PNG; 229 int initted = IMG_Init(flags); 230 if((initted&flags) != flags) { 231 if (!(IMG_INIT_PNG & initted)) 232 writefln("IMG_Init: Failed to init required png support!"); 233 throw new Exception(format("IMG_Init: %s\n", 234 IMG_GetError().to!string())); 235 } 236 } 237 238 void initSDLMixer() 239 { 240 DerelictSDL2Mixer.load(); 241 242 // load support for the OGG sample/music formats 243 int flags=MIX_INIT_OGG; 244 int initted=Mix_Init(flags); 245 if((initted&flags) != flags) { 246 if (!(MIX_INIT_OGG & initted)) 247 writefln("Mix_Init: Failed to init required ogg support!"); 248 throw new Exception(format("IMG_Init: %s\n", 249 Mix_GetError().to!string())); 250 } 251 252 if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1) { 253 throw new Exception(format("Mix_OpenAudio: %s\n", 254 Mix_GetError().to!string())); 255 } 256 } 257 258 void initAllSDLLibs(size_t display = 0) 259 { 260 initSDLImage(); 261 initSDLMixer(); 262 initSDL(display); 263 } 264 265 void deInitAllSDLLibs() 266 { 267 Mix_CloseAudio(); 268 Mix_Quit(); 269 IMG_Quit(); 270 deInitSDL(); 271 } 272 273 this(bool force_recover = false, size_t display = 0) 274 { 275 initAllSDLLibs(display); 276 keybar = new KeyBar_Buttons(this, renderer, null); 277 startGame(); 278 } 279 280 ~this() 281 { 282 stopGame(); 283 deInitAllSDLLibs(); 284 } 285 } 286